iT邦幫忙

2024 iThome 鐵人賽

DAY 6
0

Day15 要撰寫的是待辦清單,並把資料存進瀏覽器的 LocalStorage

資料

  const [todos, setTodos] = useState<Todo[]>(() => {
    const storedTodos = localStorage.getItem("todos");
    return storedTodos ? JSON.parse(storedTodos) : [];
  });
  const [newTodo, setNewTodo] = useState<string>("");

更新待辦事項

  const updateTodos = (newTodos: Todo[]) => {
    localStorage.setItem("todos", JSON.stringify(newTodos));
    setTodos(newTodos);
  };

新增

  const addTodo = () => {
    if (!newTodo.trim()) {
      return;
    }

    const newTodos: Todo[] = [
      ...todos,
      { id: Date.now(), text: newTodo, done: false },
    ];
    updateTodos(newTodos);
    setNewTodo("");
  };

  const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
    if (e.key === "Enter") {
      addTodo();
    }
  };

切換狀態

  const toggleTodo = (id: number) => {
    const newTodos = todos.map((todo) =>
      todo.id === id ? { ...todo, done: !todo.done } : todo
    );
    updateTodos(newTodos);
  };

移除

  const removeTodo = (id: number) => {
    const newTodos = todos.filter((todo) => todo.id !== id);
    updateTodos(newTodos);
  };

畫面結構


  return (
    <div className="max-w-md mx-auto mt-10 p-6 bg-white rounded-lg shadow-xl">
      <h1 className="text-2xl font-bold mb-4">Todo List</h1>

      <div className="mb-4">
        <input
          type="text"
          value={newTodo}
          onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
            setNewTodo(e.target.value)
          }
          onKeyDown={handleKeyDown}
          placeholder="Add a new todo"
          className="w-full p-2 border border-gray-300 rounded"
        />
        <button
          type="button"
          onClick={addTodo}
          className="mt-2 w-full bg-blue-500 text-white p-2 rounded hover:bg-blue-600"
        >
          Add Todo
        </button>
      </div>

      <ul>
        {todos.map((todo) => (
          <li
            key={todo.id}
            className="flex items-center justify-between p-2 border-b"
          >
            <p
              className={`flex-grow cursor-pointer ${
                todo.done ? "line-through text-gray-500" : ""
              }`}
              onClick={() => toggleTodo(todo.id)}
            >
              {todo.text}
            </p>

            <button
              type="button"
              onClick={() => removeTodo(todo.id)}
              className="ml-2 text-red-500 hover:text-red-700"
            >
              Delete
            </button>
          </li>
        ))}
      </ul>
    </div>
  );
}

DEMO

https://codesandbox.io/p/devbox/xwh89n


上一篇
[Day14]_JavaScript-References-VS-Copying
下一篇
[Day16]_Mouse-Move-Shadow
系列文
React30——用 React 探索 JavaScript30 的魅力30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言